#include "WorldEntity.h"
#include "Visualisation.h"
#include "WorldModel.h"

CWorldEntity::CWorldEntity (void): m_position(D3DXVECTOR3(0, 0, 0)), m_pitch(0), m_yaw(0), m_roll(0), m_previousPosition(D3DXVECTOR3(0, 0, 0)),
					m_previousPitch(0), m_previousYaw(0), m_previousRoll(0), m_gfxIndex(-1), m_side(eSideNeutral), m_speed(0), m_detectCollision(false),
					m_collisionCost(0), m_indexSound(-1), m_lastTimeSoundPlayed(DWORD(-1)), m_durationSound(0)

{
}

CWorldEntity::~CWorldEntity(void)
{
}


bool CWorldEntity::calculBoundingBox()
{
	BYTE* pVertices=0;

	HRESULT hr=VIS->getMesh(m_gfxIndex)->LockVertexBuffer(D3DLOCK_READONLY, (LPVOID*)&pVertices);
	if(FAILED(hr))
		return false;

	D3DXComputeBoundingBox((D3DXVECTOR3*)pVertices, VIS->getMesh(m_gfxIndex)->GetNumVertices(), D3DXGetFVFVertexSize(VIS->getMesh(m_gfxIndex)->GetFVF()),
		&m_minBounds, &m_maxBounds);

	VIS->getMesh(m_gfxIndex)->UnlockVertexBuffer();
	return true;
}

void CWorldEntity::calculOBBBoundingBox()
{
	m_obbBoundingBox[0] = D3DXVECTOR3( m_minBounds.x, m_minBounds.y, m_minBounds.z ); 
	m_obbBoundingBox[1] = D3DXVECTOR3( m_maxBounds.x, m_minBounds.y, m_minBounds.z ); 
	m_obbBoundingBox[2] = D3DXVECTOR3( m_minBounds.x, m_maxBounds.y, m_minBounds.z ); 
	m_obbBoundingBox[3] = D3DXVECTOR3( m_maxBounds.x, m_maxBounds.y, m_minBounds.z ); 
	m_obbBoundingBox[4] = D3DXVECTOR3( m_minBounds.x, m_minBounds.y, m_maxBounds.z ); 
	m_obbBoundingBox[5] = D3DXVECTOR3( m_maxBounds.x, m_minBounds.y, m_maxBounds.z ); 
	m_obbBoundingBox[6] = D3DXVECTOR3( m_minBounds.x, m_maxBounds.y, m_maxBounds.z );  
	m_obbBoundingBox[7] = D3DXVECTOR3( m_maxBounds.x, m_maxBounds.y, m_maxBounds.z ); 
}

void CWorldEntity::calculBoundingBoxIntoWorldSpace()
{
	//pitch rotation
	D3DXMATRIX pitchMatrix;
	D3DXMatrixRotationX(&pitchMatrix, m_pitch);
	//yaw rotation
	D3DXMATRIX yawMatrix;
	D3DXMatrixRotationY(&yawMatrix, m_yaw);
	//roll rotation
	D3DXMATRIX rollMatrix;
	D3DXMatrixRotationZ(&rollMatrix, m_roll);

	D3DXMATRIX translationMatrix;
	D3DXMatrixTranslation(&translationMatrix,m_position.x, m_position.y, m_position.z);
	D3DXMATRIX worldMatrix;
	worldMatrix=(pitchMatrix*yawMatrix*rollMatrix)*translationMatrix;

	for( int i = 0; i < 8; i++ )
		D3DXVec3TransformCoord( &m_worldBoundingBox[i], &m_obbBoundingBox[i], &worldMatrix );

	m_worldMinBounds.x=m_worldMaxBounds.x=m_worldBoundingBox[0].x;
	m_worldMinBounds.y=m_worldMaxBounds.y=m_worldBoundingBox[0].y;
	m_worldMinBounds.z=m_worldMaxBounds.z=m_worldBoundingBox[0].z;

	for (int i=1;i<8;i++)
	{
		if (m_worldBoundingBox[i].x < m_worldMinBounds.x) 
			m_worldMinBounds.x=m_worldBoundingBox[i].x;
		if (m_worldBoundingBox[i].x > m_worldMaxBounds.x) 
			m_worldMaxBounds.x=m_worldBoundingBox[i].x;
		if (m_worldBoundingBox[i].y < m_worldMinBounds.y)
			m_worldMinBounds.y=m_worldBoundingBox[i].y;
		if (m_worldBoundingBox[i].y > m_worldMaxBounds.y) 
			m_worldMaxBounds.y=m_worldBoundingBox[i].y;
		if (m_worldBoundingBox[i].z < m_worldMinBounds.z) 
			m_worldMinBounds.z=m_worldBoundingBox[i].z;
		if (m_worldBoundingBox[i].z > m_worldMaxBounds.z) 
			m_worldMaxBounds.z=m_worldBoundingBox[i].z;
	}
}

bool CWorldEntity::checkCollisionWith(CWorldEntity* const entity)
{
	bool collideX=false;
	bool collideY=false;
	bool collideZ=false;

	if(m_worldMaxBounds.x>=entity->getWorldMinBounds()->x && m_worldMinBounds.x<=entity->getWorldMaxBounds()->x)
		collideX=true;
	/*if(m_worldMinBounds.x<=entity->getWorldMaxBounds()->x)
		collideX=true;*/

	if(m_worldMaxBounds.y>=entity->getWorldMinBounds()->y && m_worldMinBounds.y<=entity->getWorldMaxBounds()->y)
		collideY=true;
	/*if(m_worldMinBounds.y<=entity->getWorldMaxBounds()->y)
		collideY=true;*/

	if(m_worldMaxBounds.z>=entity->getWorldMinBounds()->z && m_worldMinBounds.z<=entity->getWorldMaxBounds()->z)
		collideZ=true;
	/*if(m_worldMinBounds.z<=entity->getWorldMaxBounds()->z)
		collideZ=true;*/

	if(collideX && collideY && collideZ)
		return true;

	return false;
}

int CWorldEntity::getSide()const
{
	return m_side;
}

D3DXVECTOR3* CWorldEntity::getWorldMinBounds()
{
	return &m_worldMinBounds;
}

D3DXVECTOR3* CWorldEntity::getWorldMaxBounds()
{
	return &m_worldMaxBounds;
}

bool CWorldEntity::getDetectCollision()const
{
	return m_detectCollision;
}
D3DXVECTOR3 CWorldEntity::getPosition()const
{
	return m_position;
}

float CWorldEntity::getYaw()const
{
	return m_yaw;
}

float CWorldEntity::getDamage()const
{
	return m_collisionCost;
}